package com.bjbn.service;

import com.bjbn.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.UUID;

/**
 * WebAPI服务类
 *
 * @author bjbn
 */
@Service
public class Webapi4SimpService {

    @Autowired
    @Qualifier("httpWebClient")
    private WebClient httpWebClient;

    private final String xHwId = "jichang_io.security.integrated.management.platform_SIMP";

    private final String xHwAppkey = "8Cq$xZ!.uF/KtO-2#.KbVzlj8QI917pJ+6E-!uT+XkhLX-$//5s%M$3nNt1R47ns";

    @Value("${external.api.headers.appkey}")
    private String appkey;

    @Value("${external.api.headers.appsecret}")
    private String appsecret;

    /**
     * 转发API请求（HTTP）
     *
     * @param endpoint    API端点
     * @param version     api版本号
     * @param requestBody 请求体
     * @return 响应结果
     */
    private Mono<Map<String, Object>> forwardHttpApiRequest(String endpoint, String version, Object requestBody) {
        // 请求id {请求方系统缩略语}-{时间字符串}-{UUID前8位}
        String systemName = "DTS";
        String requestId = systemName + "-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-" + UUID.randomUUID().toString().substring(0, 8);

        return httpWebClient.post()
                .uri(endpoint)
                .header("X-HW-ID", xHwId)
                .header("X-HW-APPKEY", xHwAppkey)
                .header("Content-Type", "application/json")
                .header("appkey", appkey)
                .header("appsecret", appsecret)
                .header("timestamp", String.valueOf(System.currentTimeMillis()))
                .header("version", version)
                .header("requestId", requestId)
                .bodyValue(requestBody)
                .retrieve()
                // 关键修复：保留后端原始错误响应
                .onStatus(status -> status.is4xxClientError() || status.is5xxServerError(),
                        response -> response.bodyToMono(String.class)
                                .flatMap(errorBody -> {
                                    String errorMsg = String.format(
                                            "API调用失败: [状态码=%s] [requestId=%s] [URL=%s] [响应体=%s]",
                                            response.statusCode(), requestId, endpoint, errorBody
                                    );
                                    System.err.println(errorMsg);
                                    // 抛出异常，让上游处理或返回500
                                    return Mono.error(new RuntimeException(errorMsg));
                                })
                )
                .bodyToMono(Map.class)
                .cast(Map.class)
                .map(map -> (Map<String, Object>) map)
                // 只处理网络异常等底层错误，不处理HTTP业务错误
                .onErrorResume(WebClientRequestException.class, e -> {
                    String errorMsg = String.format(
                            "网络异常: [requestId=%s] [URL=%s] [错误=%s]",
                            requestId, endpoint, e.getMessage()
                    );
                    System.err.println(errorMsg);
                    return Mono.error(new RuntimeException(errorMsg));
                });
    }

    // ==================== 航空安保一体化平台API ====================

    /**
     * 人像检索-分析（人脸检测）
     *
     * @param request 人脸检测请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> faceDetect(SimpFaceDetectRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/assupUsers/getFaceVectorByMinioUrls", "1.0", request);
    }

    /**
     * 人像检索-以图搜图+轨迹检索
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  请求参数
     * @return 响应结果
     */
    public Mono<Map<String, Object>> faceSearch(Long pageSize, Long page, SimpFaceSearchRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getPageListByUserPicUnionDynamic?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

    /**
     * 轨迹检索（携带抓拍信息）
     *
     * @param request
     * @return
     */
    public Mono<Map<String, Object>> trajectoryRetrieval(SimpTrajectoryRetrievalRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/api/iotassup/guest/assupPersonnel/getPageListByUserPicUnionDynamicWithCaptureRecords?pageSize=" + request.getPageSize() + "&page=" + request.getPage(), "1.0", request);
    }

    /**
     * 人像检索-属性检索
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  请求参数
     * @return 响应结果
     */
    public Mono<Map<String, Object>> faceAttributeSearch(Long pageSize, Long page, SimpFaceAttributeRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getPageListByUserPicUnionProperty?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

    /**
     * 智能人像-抓拍记录以图搜图
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  请求参数
     * @return 响应结果
     */
    public Mono<Map<String, Object>> captureSearch(Long pageSize, Long page, SimpCaptureSearchRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getCaptureRecordsByPic?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

    /**
     * 人像检索-抓拍详情查询
     *
     * @param request 请求参数
     * @return 响应结果
     */
    public Mono<Map<String, Object>> captureDetailQuery(SimpCaptureDetailRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getCaptureRecordsByVO/snapshotDetailsQuery", "1.0", request);
    }

    /**
     * 人脸相似度比对
     *
     * @param request 人脸相似度比对请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> faceCompare(SimpFaceCompareRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/assupUsers/comPics", "1.0", request);
    }

    /**
     * 人脸1：N比对
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  人脸1：N比对请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> face1NCompare(Long pageSize, Long page, SimpFace1NRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getPageListByUserPicUnionDynamic/groupRecog?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

    /**
     * 检索图片中人脸的建档记录
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  检索建档记录请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> trackSearchPid(Long pageSize, Long page, SimpTrackSearchPidRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getPageListByUserPicUnionDynamic/trackSearchPid?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

    /**
     * 检索人脸建档的轨迹数据
     *
     * @param request 检索轨迹数据请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> trackSearch(SimpTrackSearchRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getCaptureRecordsByVO", "1.0", request);
    }

    /**
     * 检索人脸建档的轨迹抓拍详情数据
     *
     * @param request 检索轨迹抓拍详情请求
     * @return 响应结果
     */
    public Mono<Map<String, Object>> trackSearchDetail(SimpTrackSearchDetailRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/getCaptureRecordsByVO/trackSearchDetail", "1.0", request);
    }

    /**
     * 下载轨迹抓拍详情视频
     *
     * @param streamKey 摄像头编码
     * @param timestamp 抓拍时间点
     * @return 响应结果
     */
    public Mono<Map<String, Object>> trackVideo(String streamKey, Long timestamp) {
        return httpWebClient.get()
                .uri("/CAN/SIMP/securityIntegratedManagementPlatform/V1/assupHlsSegment/getBlobvirtualM3u8?streamKey=" + streamKey + "&timestamp=" + timestamp)
                .header("X-HW-ID", xHwId)
                .header("X-HW-APPKEY", xHwAppkey)
                .header("Content-Type", "application/json")
                .header("appkey", appkey)
                .header("appsecret", appsecret)
                .header("timestamp", String.valueOf(System.currentTimeMillis()))
                .header("version", "1.0")
                .retrieve()
                .bodyToMono(Map.class)
                .cast(Map.class)
                .map(map -> (Map<String, Object>) map)
                .onErrorResume(e -> {
                    // 记录错误日志
                    System.err.println("HTTP API转发失败: /CAN/SIMP/securityIntegratedManagementPlatform/V1/assupHlsSegment/getBlobvirtualM3u8, 错误: " + e.getMessage());
                    return Mono.empty();
                });
    }

    /**
     * 人员结构化信息查询（特征查询）
     *
     * @param pageSize 每页大小
     * @param page     当前页
     * @param request  请求参数
     * @return 响应结果
     */
    public Mono<Map<String, Object>> structuredPerson(Long pageSize, Long page, SimpStructuredPersonRequest request) {
        return forwardHttpApiRequest("/CAN/SIMP/securityIntegratedManagementPlatform/V1/api/iotassup/guest/assupUsers/getNewStructuredPerson?pageSize=" + pageSize + "&page=" + page, "1.0", request);
    }

} 